/**
*	@class Clock
*
*	@brief A clock class that can be used for Timing
*
*	@author William McVicar
*/

#pragma once
#ifndef __CLOCK_H_INCLUDED__
#define __CLOCK_H_INCLUDED__

// Library Includes

// Local Includes

// Types

// Constants

// Prototypes

// Forward Declarations

namespace Protein
{

class Clock
{
	//// Member Functions
public:

	Clock();
	Clock( const Clock& other );
	Clock& operator=( const Clock& rhs );
	~Clock(){};

	bool Initialise();
	void Update();
	void Reset();
	double GetTimeAbsoluteD();
	inline bool IsFrozen() const;
	inline u32 GetTick() const;
	inline float GetTickF() const;
	inline float GetFrameRate() const;
	inline u32 GetTimeAbsolute();
	inline float GetTimeAbsoluteF();

protected:

private:

	////Member Variables
public:

protected:

private:

	bool									m_bUsingQPF;
	bool									m_bInPlay;

	i64										m_llQPFTicksPerSec;
	i64										m_llStopTime;
	i64										m_llQPFLastTick;
	i64										m_llBaseTime;
	i64										m_llQPFTick;

	u32										m_uiTick;
	u32										m_uiLastTick;
	u32										m_uiStartTick;
	u32										m_uiFRCount;

	float										m_fFrameRateAggregator;
	float										m_fFrameRate;
};

PROTEIN_INLINE u32 Clock::GetTick() const
{
	return m_uiTick;
}

PROTEIN_INLINE float Clock::GetTickF() const
{
	if( !m_bUsingQPF )
		return(static_cast<float>(m_uiTick - m_uiLastTick) / 1000.0f);
	else
		return( static_cast<float>( m_llQPFTick - m_llQPFLastTick ) / static_cast<float>( m_llQPFTicksPerSec ) );
}

PROTEIN_INLINE float Clock::GetFrameRate() const
{
	return m_fFrameRate;
}

PROTEIN_INLINE u32 Clock::GetTimeAbsolute()
{
	return timeGetTime();
}

PROTEIN_INLINE float Clock::GetTimeAbsoluteF()
{
	return static_cast< float >( GetTimeAbsoluteD() );
}

}

#endif // __CLOCK_H_INCLUDED__
